/*
 * Copyright 2002-2006 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 control.add(getTaskPanel(), "0, 0, 1, 3");
 * License for the specific language governing permissions and limitations under
 * the License.
 import com.jgoodies.forms.layout.FormLayout;
 */
package net.jwtools.tmt.ui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import net.jwtools.tmt.domain.IVisit;
import net.jwtools.tmt.domain.MainVisit;
import net.jwtools.tmt.domain.ReVisit;
import net.jwtools.tmt.domain.Status;
import net.jwtools.tmt.service.IVisitService;
import net.jwtools.tmt.ui.table.TerritoryHistoryVisitsTable;

import org.jdesktop.swingx.JXLabel;
import org.springframework.binding.value.ValueModel;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.richclient.application.PageComponentContext;
import org.springframework.richclient.application.event.LifecycleApplicationEvent;
import org.springframework.richclient.application.support.AbstractView;
import org.springframework.richclient.command.GuardedActionCommandExecutor;
import org.springframework.richclient.command.support.AbstractActionCommandExecutor;
import org.springframework.richclient.dialog.ConfirmationDialog;
import org.springframework.richclient.dialog.MessageDialog;
import org.springframework.richclient.list.ListSelectionValueModelAdapter;
import org.springframework.richclient.list.ListSingleSelectionGuard;

import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.swing.EventComboBoxModel;

public class CheckinView extends AbstractView implements ApplicationListener {
	{
		// Set Look & Feel
		try {
			javax.swing.UIManager
					.setLookAndFeel("com.jgoodies.looks.plastic.Plastic3DLookAndFeel");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * Handler for the "New Contact" action.
	 */
	private GuardedActionCommandExecutor checkinExecutor = new CheckinExecutor();
	private GuardedActionCommandExecutor detailsExecutor = new DetailsExecutor();

	private IVisitService visitService;
	private TerritorySelectInfoForm infoForm;
	private EventList<IVisit> visits;
	private JComboBox visitsComboBox;
	private EventComboBoxModel<IVisit> visitsComboBoxModel;
	private TerritoryHistoryVisitsTable historyVisitsTable;

	/**
	 * Default constructor.
	 */
	public CheckinView() {
	}

	public IVisitService getVisitService() {
		return visitService;
	}

	public void setVisitService(IVisitService visitService) {
		this.visitService = visitService;
	}

	protected void initListeners() {

	}

	protected void showNoVisitsDialog() {
		String title = getMessage("checkinView.noCheckedOut.title");
		String message = getMessage("checkinView.noCheckedOut.message");
		new MessageDialog(title, message).showDialog();
	}

	protected void checkControl() {
		if (!getControl().isVisible()) {
			getControl().setVisible(true);
		} else if (getControl().getComponent(0) instanceof JXLabel) {
			getControl().remove(0);
			getControl().add(createControl());
		}
	}

	/**
	 * Register the local command executors to be associated with named
	 * commands. This is called by the platform prior to making the view
	 * visible.
	 */
	protected void registerLocalCommandExecutors(PageComponentContext context) {
		context.register("checkinCommand", checkinExecutor);
	}

	/**
	 * Handle an application event. This will notify us of object adds, deletes,
	 * and modifications. Update our table model accordingly.
	 * 
	 * @param e
	 *            event to process
	 */
	public void onApplicationEvent(ApplicationEvent e) {
		if (e instanceof LifecycleApplicationEvent) {
			LifecycleApplicationEvent le = (LifecycleApplicationEvent) e;
			IVisit eventObject = (IVisit) le.getObject();
			logger.debug("CheckinView got " + le.getEventType() + " for "
					+ eventObject.getId() + "=" + eventObject);
			if (le.getEventType() == LifecycleApplicationEvent.CREATED) {
				if (eventObject.getCheckinDate() == null) {
					visits.add((IVisit) le.getObject());
					checkControl();
					visitsComboBox.setSelectedIndex(0);
				}
			} else if (le.getEventType() == LifecycleApplicationEvent.DELETED) {
				// visits.add((IVisit)le.getObject());
			}
		}
	}

	@Override
	protected JComponent createControl() {
		visits = GlazedLists.eventList(getVisitService().getAllOutstanding());
		FlowLayout cpLayout = new FlowLayout();
		cpLayout.setAlignment(FlowLayout.LEFT);
		cpLayout.setHgap(30);
		JPanel cp = new JPanel(cpLayout);
		if (visits.size() > 0) {
			visitsComboBox = getComponentFactory().createComboBox();
			visitsComboBoxModel = new EventComboBoxModel<IVisit>(visits);
			visitsComboBox.setModel(visitsComboBoxModel);
			infoForm = new TerritorySelectInfoForm(visits.get(0));
			historyVisitsTable = new TerritoryHistoryVisitsTable();
			visitsComboBox.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					IVisit visit = (IVisit) ((JComboBox) e.getSource())
							.getSelectedItem();
					infoForm.setFormObject(visit);
					infoForm.getFormModel().validate();
					IVisit mv = visit.getBelongsTo();
					if (mv == null)
						mv = visit;
					historyVisitsTable.setMainVisit(mv);
				}
			});
			infoForm.setVisitsComboBox(visitsComboBox);
			visitsComboBox.setSelectedIndex(0);
			JComponent form = infoForm.createFormControl();
			form.setAlignmentX(1.0f);
			cp.add(form);
			if (visits.get(0) instanceof ReVisit) historyVisitsTable.setMainVisit(visits.get(0).getBelongsTo());
			else historyVisitsTable.setMainVisit(visits.get(0));
			
			historyVisitsTable.setStatusBar(getStatusBar());
			ValueModel selectionHolder = new ListSelectionValueModelAdapter(
					historyVisitsTable.getSelectionModel());
			new ListSingleSelectionGuard(selectionHolder, detailsExecutor);
			historyVisitsTable.setClickHandler(detailsExecutor);
			JPanel hvtPanel = new JPanel(new BorderLayout());
			JScrollPane sp = getComponentFactory().createScrollPane(
					historyVisitsTable.getControl());
			sp.setPreferredSize(new Dimension(400, 150));
			hvtPanel.add(getComponentFactory().createLabeledSeparator(
					"checkinView.historyTable.title"), BorderLayout.NORTH);
			hvtPanel.add(sp, BorderLayout.CENTER);
			cp.add(hvtPanel);
		} else {
			cp.add(new JXLabel(getMessage("checkinView.noCheckedOut.message")));
		}
		return cp;
	}

	/**
	 * Private inner class to create a new contact.
	 */
	private class CheckinExecutor extends AbstractActionCommandExecutor {
		IVisit currentVisit;

		public void execute() {
			infoForm.getFormModel().commit();
			// Update the persistent store with the new/modified object.
			currentVisit = (IVisit) infoForm.getFormModel().getFormObject();
			
			if (infoForm.getPreviousAbsent().equals(
					currentVisit.getNotHomeNumber())) {
				String title = getMessage("checkinView.confirmAbsent.title");
				String message = getMessage("checkinView.confirmAbsent.message");
				ConfirmationDialog dlg = new ConfirmationDialog(title, message) {
					protected void onConfirm() {
						save();
					}
				};
				dlg.showDialog();
			} else
				save();
		}

		private void save() {
			
			if (currentVisit.getNotHomeNumber()==0 | infoForm.isFinished()) {
				if (currentVisit instanceof MainVisit) {
					currentVisit.setReadyDate(currentVisit.getCheckinDate());
					currentVisit.setNotHomeNumber(null);
					// And notify the rest of the application of the change
					getApplicationContext().publishEvent(
							new LifecycleApplicationEvent(
									LifecycleApplicationEvent.CREATED, currentVisit));

				} else {
					// a ReVisit so mark the mainvisit as ready and active
					currentVisit.getBelongsTo().setReadyDate(currentVisit.getCheckinDate());
					currentVisit.getBelongsTo().setStatus(Status.ACTIVE);
					currentVisit.getBelongsTo().setNotHomeNumber(null);
					currentVisit.setStatus(Status.INACTIVE);
					getApplicationContext().publishEvent(
							new LifecycleApplicationEvent(
									LifecycleApplicationEvent.CREATED, currentVisit.getBelongsTo()));
					getApplicationContext().publishEvent(
							new LifecycleApplicationEvent(
									LifecycleApplicationEvent.DELETED, currentVisit));
				}
			}else {
				// And notify the rest of the application of the change
				getApplicationContext().publishEvent(
						new LifecycleApplicationEvent(
								LifecycleApplicationEvent.CREATED, currentVisit));
			}
			visitService.save(currentVisit);
			// remove from the visits lists
			visits.remove(currentVisit);
			if (visitsComboBoxModel.getSize() == 0) {
				// alert and hide the form
				getControl().setVisible(false);
				showNoVisitsDialog();
			} else {
				visitsComboBox.setSelectedIndex(0);
			}
		}
	}

	private class DetailsExecutor extends AbstractActionCommandExecutor {
		public void   execute() {
			final IVisit visit = historyVisitsTable.getSelectedVisit();
					System.out.println(visit.getTotalDaysCheckedout());
				}
//				if (visit.equals(visitsComboBox.getSelectedItem())) {
//					Color tmp = visitsComboBox.getBackground();
//					visitsComboBox.setBackground(Color.red);
//					visitsComboBox.setBackground(tmp);
//				}
			}
}
